package com.systemCapacity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.systemCapacity.common.dto.*;
import com.systemCapacity.entity.Attribute;
import com.systemCapacity.entity.Enum.AttributeType;
import com.systemCapacity.entity.Enum.PlatformType;
import com.systemCapacity.entity.Enum.TemplateType;
import com.systemCapacity.entity.Equipment;
import com.systemCapacity.entity.EquipmentTemplate;
import com.systemCapacity.mapper.EquipmentTemplateMapper;
import com.systemCapacity.service.AttributeService;
import com.systemCapacity.service.EquipmentService;
import com.systemCapacity.service.EquipmentTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class EquipmentTemplateServiceImpl extends ServiceImpl<EquipmentTemplateMapper, EquipmentTemplate>
        implements EquipmentTemplateService {

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    EquipmentTemplateMapper equipmentTemplateMapper;

    @Autowired
    private AttributeService attributeService;

    @Override
    public List<EquipmentTemplateDto> getTemplates(int type, int belong, int page, int size) {
        QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("templateType", type);
        queryWrapper.eq("templateBelong", belong);
        queryWrapper.orderByAsc("platformType");
        Page<EquipmentTemplate> equipmentTemplatePage = new Page<>(page, size);
        List<EquipmentTemplate> templates = equipmentTemplateMapper.selectList(queryWrapper);
        List<EquipmentTemplateDto> dtos = templates.stream()
                .map(equipmentTemplate -> BeanUtil.copyProperties(equipmentTemplate, EquipmentTemplateDto.class))
                .collect(Collectors.toList());
        for (EquipmentTemplateDto dto : dtos) {
            dto.setAttributes(attributeService.getTemplateAttributes(dto.getTemplateId()));
            dto.setEquipments(equipmentService.getChildEquipment(dto.getTemplateId()));
        }
        return dtos;
    }

    /**
     * 保存作战装备模板
     * @param dto 装备模板
     * @return 保存结果
     */
    @Override
    @Transactional
    public boolean saveEquipmentTemplate(EquipmentTemplateDto dto) {
        EquipmentTemplate template = new EquipmentTemplate();
        template.setTemplateName(dto.getTemplateName());
        template.setTemplateType(dto.getTemplateType().getValue());
        template.setTemplateId(UUID.randomUUID().toString());
        template.setTemplateBelong(dto.getBelong());
        if (dto.getPlatformType() != null) {
            template.setPlatformType(dto.getPlatformType().getValue());
        }
        save(template);
        for (AttributeDto attr : dto.getAttributes()) {
            attr.setAttributeType(AttributeType.TEMPLATE);
            attr.setAttributeId(UUID.randomUUID().toString());
            attributeService.saveAttribute(template.getTemplateId(), attr);
        }
        return true;
    }

    /**
     * 判断作战装备模板id是否存在
     * @param templateId 作战装备模板id
     * @return 是否存在
     */
    @Override
    public boolean templateExist(String templateId) {
        QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("templateId", templateId);
        return getOne(queryWrapper) != null;
    }

    /**
     * 判断作战装备模板名是否存在
     * @param templateName 作战装备模板名
     * @return 是否存在
     */
    @Override
    public boolean templateNameExist(String templateName) {
        QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("templateName", templateName);
        return getOne(queryWrapper) != null;
    }

    /**
     * 编辑作战装备模板
     * @param dto 装备模板
     * @return 编辑结果
     */
    @Override
    @Transactional
    public boolean editEquipmentTemplate(EquipmentTemplateDto dto) {
        LambdaUpdateWrapper<EquipmentTemplate> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(EquipmentTemplate::getTemplateId, dto.getTemplateId())
                .set(EquipmentTemplate::getTemplateName, dto.getTemplateName());
        update(lambdaUpdateWrapper);

        List<EquipmentDto> equipments = equipmentService.getChildEquipment(dto.getTemplateId());

        if (dto.getAttributes() == null) {
            return true;
        }

        for (AttributeDto attribute : dto.getAttributes()) {
            // 新增模板属性
            if (attribute.getAttributeId() == null) {
                attribute.setAttributeId(UUID.randomUUID().toString());
                attributeService.saveAttribute(dto.getTemplateId(), attribute);
                // 向所有子装备添加装备模板
                for (EquipmentDto equipment : equipments) {
                    AttributeDto eAttribute = new AttributeDto();
                    eAttribute.setAttributeId(UUID.randomUUID().toString());
                    eAttribute.setPid(attribute.getAttributeId());
                    eAttribute.setEquipmentId(equipment.getEquipmentId());
                    eAttribute.setAttributeValueType(attribute.getAttributeValueType());
                    eAttribute.setUnit(attribute.getUnit());
                    eAttribute.setAttributeType(AttributeType.EQUIPMENT);
                    eAttribute.setAttributeName(attribute.getAttributeName());
                    switch (eAttribute.getAttributeValueType()) {
                        case NUMERIC:
                            eAttribute.setValues(new ArrayList<>(Collections.singletonList(0.0)));
                            break;
                        case RANGE:
                            eAttribute.setValues(new ArrayList<>(Arrays.asList(0.0, 0.0)));
                    }
                    attributeService.saveAttribute(equipment.getEquipmentId(), eAttribute);
                }
            } else {
                // 编辑模板属性
                Attribute origin = attributeService.getById(attribute.getAttributeId());
                attributeService.editAttribute(attribute);
                // 修改对应装备属性
                AttributeDto eAttribute = new AttributeDto();
                eAttribute.setAttributeName(attribute.getAttributeName());
                eAttribute.setAttributeValueType(attribute.getAttributeValueType());
                eAttribute.setUnit(attribute.getUnit());
                eAttribute.setPid(attribute.getAttributeId());
                // 属性没有变化不能初始化装备值
                if (origin.getAttributeValueType() != attribute.getAttributeValueType()) {
                    switch (eAttribute.getAttributeValueType()) {
                        case NUMERIC:
                            eAttribute.setValues(new ArrayList<>(Collections.singletonList(0.0)));
                            break;
                        case RANGE:
                            eAttribute.setValues(new ArrayList<>(Arrays.asList(0.0, 0.0)));
                    }
                }
                attributeService.updateChildAttribute(eAttribute);
            }
        }
        return true;
    }

    /**
     * 查询模板所属平台类型
     * @param templates 装备模板
     * @return 模板所属平台类型
     */
    @Override
    public List<Integer> getTemplateType(List<String> templates) {
        if (templates.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("templateId", templates);
        queryWrapper.select("DISTINCT templateType");
        return equipmentTemplateMapper.selectList(queryWrapper).stream()
                .map(EquipmentTemplate::getTemplateType).collect(Collectors.toList());
    }

    @Override
    public List<TemplateMenuDto> getTemplateMenu(Integer taskType) {
        List<TemplateMenuDto> dtos = new ArrayList<>();
        for (TemplateType type : TemplateType.values()) {
            if (type == TemplateType.PLATFORM) {
                continue;
            }
            TemplateMenuDto dto = new TemplateMenuDto();
            dto.setType(type);
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", type.getValue());
            queryWrapper.eq("templateBelong", taskType);
            List<SimplifiedTemplateDto> simplifiedTemplateDtos = equipmentTemplateMapper.selectList(queryWrapper)
                    .stream().map(template -> BeanUtil.copyProperties(template, SimplifiedTemplateDto.class))
                    .collect(Collectors.toList());
            if (simplifiedTemplateDtos.isEmpty()) {
                continue;
            }
            dto.setChildren(simplifiedTemplateDtos);
            simplifiedTemplateDtos.forEach(simplifiedTemplateDto ->
                            simplifiedTemplateDto.setChildren(equipmentService.getChildEquipment(
                                    simplifiedTemplateDto.getTemplateId()).stream()
                                    .map(equipmentDto -> BeanUtil.copyProperties(equipmentDto, SimplifiedEquipmentDto.class))
                                    .collect(Collectors.toList())));
            dtos.add(dto);
        }
        getPlatformMenu(dtos);
        return dtos;
    }

    @Override
    public List<TemplateMenuDto> getBlueTemplateMenu() {
        List<TemplateMenuDto> dtos = new ArrayList<>();
        for (TemplateType type : TemplateType.values()) {
            if (type == TemplateType.PLATFORM) {
                continue;
            }
            TemplateMenuDto dto = new TemplateMenuDto();
            dto.setType(type);
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", type.getValue());
            queryWrapper.eq("templateBelong", 2);
            List<SimplifiedTemplateDto> simplifiedTemplateDtos = equipmentTemplateMapper.selectList(queryWrapper)
                    .stream().map(template -> BeanUtil.copyProperties(template, SimplifiedTemplateDto.class))
                    .collect(Collectors.toList());
            if (simplifiedTemplateDtos.isEmpty()) {
                continue;
            }
            dto.setChildren(simplifiedTemplateDtos);
            simplifiedTemplateDtos.forEach(simplifiedTemplateDto ->
                    simplifiedTemplateDto.setChildren(equipmentService.getChildEquipment(
                                    simplifiedTemplateDto.getTemplateId()).stream()
                            .map(equipmentDto -> BeanUtil.copyProperties(equipmentDto, SimplifiedEquipmentDto.class))
                            .collect(Collectors.toList())));
            dtos.add(dto);
        }
        getBluePlatformMenu(dtos);
        return dtos;
    }

    @Override
    public List<TemplateMenuDto> getRedTemplateMenu() {
        List<TemplateMenuDto> dtos = new ArrayList<>();
        for (TemplateType type : TemplateType.values()) {
            if (type == TemplateType.PLATFORM) {
                continue;
            }
            TemplateMenuDto dto = new TemplateMenuDto();
            dto.setType(type);
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", type.getValue());
            queryWrapper.eq("templateBelong", 1);
            List<SimplifiedTemplateDto> simplifiedTemplateDtos = equipmentTemplateMapper.selectList(queryWrapper)
                    .stream().map(template -> BeanUtil.copyProperties(template, SimplifiedTemplateDto.class))
                    .collect(Collectors.toList());
            if (simplifiedTemplateDtos.isEmpty()) {
                continue;
            }
            dto.setChildren(simplifiedTemplateDtos);
            simplifiedTemplateDtos.forEach(simplifiedTemplateDto ->
                    simplifiedTemplateDto.setChildren(equipmentService.getChildEquipment(
                                    simplifiedTemplateDto.getTemplateId()).stream()
                            .map(equipmentDto -> BeanUtil.copyProperties(equipmentDto, SimplifiedEquipmentDto.class))
                            .collect(Collectors.toList())));
            dtos.add(dto);
        }
        getRedPlatformMenu(dtos);
        return dtos;
    }

    /**
     * 获取蓝方平台的menu
     * @param dtos
     */
    public void getBluePlatformMenu(List<TemplateMenuDto> dtos) {
        TemplateMenuDto dto = new TemplateMenuDto();
        dto.setType(TemplateType.PLATFORM);
        dto.setChildren(new ArrayList<>());
        dto.setTemplateName("平台");
        for (PlatformType type : PlatformType.values()) {
            SimplifiedTemplateDto simplifiedTemplateDto = new SimplifiedTemplateDto();
            simplifiedTemplateDto.setTemplateName(type.getDes());
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", dto.getType().getValue());
            queryWrapper.eq("platformType", type.getValue());
            queryWrapper.eq("templateBelong", 2); //查询蓝方平台的装备模型
            // 查询平台类型的模板
            List<EquipmentTemplate> templates = equipmentTemplateMapper.selectList(queryWrapper);
            if (templates.isEmpty()) {
                continue;
            }
            simplifiedTemplateDto.setChildTemplates(new ArrayList<>());
            templates.forEach(template -> {
                // 模板下的装备
                List<EquipmentDto> equipments = equipmentService.getChildEquipment(template.getTemplateId());
                if (!equipments.isEmpty()) {
                    if (dto.getChildren().size() <= type.getValue()) {
                        dto.getChildren().add(simplifiedTemplateDto);
                    }
                    SimplifiedTemplateDto templateDto = BeanUtil.copyProperties(template, SimplifiedTemplateDto.class);
                    simplifiedTemplateDto.getChildTemplates().add(templateDto);
                    templateDto.setChildren(new ArrayList<>());
                    equipments.forEach(equipment -> templateDto.getChildren().add(BeanUtil.copyProperties(equipment, SimplifiedEquipmentDto.class)));
                }
            });
        }
        if (!dto.getChildren().isEmpty()) {
            dtos.add(dto);
        }
    }

    /**
     * 获取红方平台的menu
     * @param dtos
     */
    public void getRedPlatformMenu(List<TemplateMenuDto> dtos) {
        TemplateMenuDto dto = new TemplateMenuDto();
        dto.setType(TemplateType.PLATFORM);
        dto.setChildren(new ArrayList<>());
        dto.setTemplateName("平台");
        for (PlatformType type : PlatformType.values()) {
            SimplifiedTemplateDto simplifiedTemplateDto = new SimplifiedTemplateDto();
            simplifiedTemplateDto.setTemplateName(type.getDes());
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", dto.getType().getValue());
            queryWrapper.eq("platformType", type.getValue());
            queryWrapper.eq("templateBelong", 1); //查询红方平台的装备模型
            queryWrapper.orderByAsc("platformType");
            // 查询平台类型的模板
            List<EquipmentTemplate> templates = equipmentTemplateMapper.selectList(queryWrapper);
            if (templates.isEmpty()) {
                continue;
            }
            simplifiedTemplateDto.setChildTemplates(new ArrayList<>());
            templates.forEach(template -> {
                // 模板下的装备
                List<EquipmentDto> equipments = equipmentService.getChildEquipment(template.getTemplateId());
                if (!equipments.isEmpty()) {
                    if (dto.getChildren().size() <= type.getValue()) {
                        dto.getChildren().add(simplifiedTemplateDto);
                    }
                    SimplifiedTemplateDto templateDto = BeanUtil.copyProperties(template, SimplifiedTemplateDto.class);
                    simplifiedTemplateDto.getChildTemplates().add(templateDto);
                    templateDto.setChildren(new ArrayList<>());
                    equipments.forEach(equipment -> templateDto.getChildren().add(BeanUtil.copyProperties(equipment, SimplifiedEquipmentDto.class)));
                }
            });
        }
        if (!dto.getChildren().isEmpty()) {
            dtos.add(dto);
        }
    }

    @Override
    public List<EquipmentTemplateDto> getRedPlatfomList(){
        QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(x -> x.eq("templateType",TemplateType.PLATFORM.getValue())
                .or()
                .eq("templateType",TemplateType.ALLEGATION.getValue()));
        queryWrapper.eq("templateBelong", 1); //查询红方平台的装备模型
        queryWrapper.orderByAsc("platformType");
        // 查询平台类型的模板
        List<EquipmentTemplate> equipmentTemplateList = equipmentTemplateMapper.selectList(queryWrapper);
        List<EquipmentTemplateDto> list = equipmentTemplateList.stream().map(x -> {
            EquipmentTemplateDto equipmentTemplateDto = BeanUtil.copyProperties(x,EquipmentTemplateDto.class);
            return equipmentTemplateDto;
        }).collect(Collectors.toList());
        return list;
    }

    /**
     * 获取装备前缀
     * @param equipment 装备
     * @return 装备前缀
     */
    @Override
    public String getPrefixByEquipmentId(Equipment equipment) {
        EquipmentTemplate template = getById(equipment.getPTemplateId());
        StringBuilder prefix = new StringBuilder();
        switch (template.getTemplateType()) {
            case 0:
                prefix.append("指控单元");
                break;
            case 1:
                prefix.append("平台");
                break;
            case 2:
                prefix.append("传感器");
                break;
            case 3:
                prefix.append("武器");
                break;
            case 4:
                prefix.append("数据链");
                break;
        }
        prefix.append("-");
        if (template.getTemplateType().intValue() == TemplateType.PLATFORM.getValue().intValue()) {
            prefix.append(PlatformType.values()[template.getPlatformType()].getDes()).append("-");
        }
        prefix.append(template.getTemplateName()).append("-");
        return prefix.toString();
    }

    public void getPlatformMenu(List<TemplateMenuDto> dtos) {
        TemplateMenuDto dto = new TemplateMenuDto();
        dto.setType(TemplateType.PLATFORM);
        dto.setChildren(new ArrayList<>());
        dto.setTemplateName("平台");
        for (PlatformType type : PlatformType.values()) {
            SimplifiedTemplateDto simplifiedTemplateDto = new SimplifiedTemplateDto();
            simplifiedTemplateDto.setTemplateName(type.getDes());
            QueryWrapper<EquipmentTemplate> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("templateType", dto.getType().getValue());
            queryWrapper.eq("platformType", type.getValue());
            // 查询平台类型的模板
            List<EquipmentTemplate> templates = equipmentTemplateMapper.selectList(queryWrapper);
            if (templates.isEmpty()) {
                continue;
            }
            simplifiedTemplateDto.setChildTemplates(new ArrayList<>());
            templates.forEach(template -> {
                // 模板下的装备
                List<EquipmentDto> equipments = equipmentService.getChildEquipment(template.getTemplateId());
                if (!equipments.isEmpty()) {
                    if (dto.getChildren().size() <= type.getValue()) {
                        dto.getChildren().add(simplifiedTemplateDto);
                    }
                    SimplifiedTemplateDto templateDto = BeanUtil.copyProperties(template, SimplifiedTemplateDto.class);
                    simplifiedTemplateDto.getChildTemplates().add(templateDto);
                    templateDto.setChildren(new ArrayList<>());
                    equipments.forEach(equipment -> templateDto.getChildren().add(BeanUtil.copyProperties(equipment, SimplifiedEquipmentDto.class)));
                }
            });
        }
        if (!dto.getChildren().isEmpty()) {
            dtos.add(dto);
        }
    }
}
